package com.gymmsystem.GYMMSystem.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gymmsystem.GYMMSystem.entity.MemberCardRecord;
import com.gymmsystem.GYMMSystem.mapper.MemberCardRecordMapper;
import com.gymmsystem.GYMMSystem.entity.MemberCardType;
import com.gymmsystem.GYMMSystem.service.MemberCardRecordService;
import com.gymmsystem.GYMMSystem.service.MemberCardTypeService;
import com.gymmsystem.GYMMSystem.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDate;
import java.util.List;

@Service
public class MemberCardRecordServiceImpl extends ServiceImpl<MemberCardRecordMapper, MemberCardRecord> implements MemberCardRecordService {
    private static final Logger log = LoggerFactory.getLogger(MemberCardRecordServiceImpl.class);

    @Autowired
    private UserService userService;
    
    @Autowired
    private MemberCardTypeService memberCardTypeService;

    @Override
    public List<MemberCardRecord> getRecordsByUserId(Long userId) {
        return baseMapper.selectRecordsWithInfo(userId);
    }

    @Override
    public IPage<MemberCardRecord> getRecordsPage(Integer pageNum, Integer pageSize) {
        Page<MemberCardRecord> page = new Page<>(pageNum, pageSize);
        return baseMapper.selectRecordsWithInfoPage(page);
    }

    @Override
    public boolean purchaseCard(MemberCardRecord record) {
        try {
            // 设置创建时间
            record.setCreatedAt(java.time.LocalDateTime.now());
            
            // 如果前端没有设置开始日期，则设为今天
            if (record.getStartDate() == null) {
                record.setStartDate(java.time.LocalDate.now());
            }
            
            // 如果前端没有设置结束日期，则默认30天后
            if (record.getEndDate() == null) {
                record.setEndDate(java.time.LocalDate.now().plusDays(30));
            }

            // 保存购买记录
            boolean saved = save(record);

            if (saved) {
                log.info("会员卡购买成功 - 用户ID: {}, 卡类型ID: {}, 价格: {}",
                        record.getUserId(), record.getCardTypeId(), record.getPurchasePrice());
                
                // 计算积分：月卡+30积分，季卡+100积分，年卡+420积分
                Integer points = 0;
                // 根据卡类型ID判断卡类型并设置相应积分
                if (record.getCardTypeId() != null) {
                    // 通过MemberCardTypeService查询完整的卡类型信息
                    MemberCardType cardType = memberCardTypeService.getById(record.getCardTypeId());
                    if (cardType != null && cardType.getCardName() != null) {
                        String cardName = cardType.getCardName();
                        // 根据卡名称判断卡类型并设置相应积分
                        if (cardName.contains("月") || cardName.contains("30天")) {
                            points = 30; // 月卡+30积分
                        } else if (cardName.contains("季") || cardName.contains("90天")) {
                            points = 100; // 季卡+100积分
                        } else if (cardName.contains("年") || cardName.contains("365天")) {
                            points = 420; // 年卡+420积分
                        } else {
                            // 其他卡类型默认给30积分
                            points = 0;
                        }
                        log.info("根据卡类型设置积分 - 卡名称: {}, 积分: {}", cardName, points);
                    } else {
                        // 如果无法获取卡类型信息，默认给30积分
                        points = 0;
                        log.warn("无法获取卡类型信息，使用默认积分 - 卡类型ID: {}", record.getCardTypeId());
                    }
                }
                
                // 计算剩余天数：根据卡类型直接添加固定天数
                Integer remainingDays = 0; // 默认0天
                // 根据卡类型ID判断卡类型并设置相应天数
                if (record.getCardTypeId() != null) {
                    // 通过MemberCardTypeService查询完整的卡类型信息
                    MemberCardType cardType = memberCardTypeService.getById(record.getCardTypeId());
                    if (cardType != null && cardType.getCardName() != null) {
                        String cardName = cardType.getCardName();
                        // 根据卡名称判断卡类型并设置相应天数
                        if (cardName.contains("月") || cardName.contains("30天")) {
                            remainingDays = 31; // 月卡加31天
                        } else if (cardName.contains("季") || cardName.contains("90天")) {
                            remainingDays = 91; // 季卡加91天
                        } else if (cardName.contains("年") || cardName.contains("365天")) {
                            remainingDays = 366; // 年卡加366天
                        } else if (cardName.contains("体验")) {
                            remainingDays = 1; // 体验卡1天
                        }
                        log.info("根据卡类型设置剩余天数 - 卡名称: {}, 天数: {}", cardName, remainingDays);
                    } else {
                        // 如果无法获取卡类型信息，默认30天
                        remainingDays = 0;
                        log.warn("无法获取卡类型信息，使用默认天数 - 卡类型ID: {}", record.getCardTypeId());
                    }
                }
                
                // 叠加更新用户积分和剩余天数
                boolean updated = userService.addUserPointsAndDays(record.getUserId(), points, remainingDays);
                if (updated) {
                    log.info("用户信息叠加更新成功 - 用户ID: {}, 新增积分: {}, 新增天数: {}",
                            record.getUserId(), points, remainingDays);
                } else {
                    log.warn("用户信息叠加更新失败 - 用户ID: {}", record.getUserId());
                }
            }

            return saved;
        } catch (Exception e) {
            log.error("会员卡购买失败 - 用户ID: {}, 错误: {}", record.getUserId(), e.getMessage());
            return false;
        }
    }

    @Override
    public boolean hasValidCard(Long userId) {
        Integer count = baseMapper.countValidCardsByUserId(userId);
        return count != null && count > 0;
    }

    @Override
    public MemberCardRecord getCurrentValidCard(Long userId) {
        List<MemberCardRecord> records = baseMapper.selectByUserId(userId);

        LocalDate today = LocalDate.now();

        return records.stream()
                .filter(record -> record.getEndDate() != null &&
                        !record.getEndDate().isBefore(today))
                .findFirst()
                .map(record -> {
                    // 计算真实的剩余天数
                    if (record.getEndDate() != null) {
                        // 使用Java 8的时间计算，确保返回真实剩余天数
                        long days = java.time.temporal.ChronoUnit.DAYS.between(today, record.getEndDate());
                        // 使用反射机制为record对象添加剩余天数字段
                        try {
                            java.lang.reflect.Field field = record.getClass().getDeclaredField("remainingDays");
                            field.setAccessible(true);
                            field.set(record, (int) Math.max(0, days));
                        } catch (Exception e) {
                            log.info("计算真实剩余天数: {}", Math.max(0, days));
                        }
                    }
                    return record;
                })
                .orElse(null);
    }
    
    @Override
    public List<MemberCardRecord> getAllValidCards(Long userId) {
        List<MemberCardRecord> records = baseMapper.selectRecordsWithInfo(userId);

        LocalDate today = LocalDate.now();

        return records.stream()
                .filter(record -> record.getEndDate() != null &&
                        !record.getEndDate().isBefore(today))
                .sorted((a, b) -> b.getEndDate().compareTo(a.getEndDate())) // 按结束日期倒序排列
                .peek(record -> {
                    // 计算真实的剩余天数
                    if (record.getEndDate() != null) {
                        // 使用Java 8的时间计算，确保返回真实剩余天数
                        long days = java.time.temporal.ChronoUnit.DAYS.between(today, record.getEndDate());
                        // 使用反射机制为record对象添加剩余天数字段
                        try {
                            // 由于MemberCardRecord类没有剩余天数字段，我们需要使用Map来包装结果
                            // 这里通过反射设置，确保前端能获取到真实的剩余天数
                            java.lang.reflect.Field field = record.getClass().getDeclaredField("remainingDays");
                            field.setAccessible(true);
                            field.set(record, (int) Math.max(0, days));
                        } catch (Exception e) {
                            // 如果没有该字段，使用JSON序列化时会自动处理额外字段
                            // 或者可以考虑扩展MemberCardRecord类添加该字段
                            log.info("计算真实剩余天数: {}", Math.max(0, days));
                        }
                    }
                })
                .toList();
    }
}